Ce tutorial fait suite au codelab oo-03-encapsulation et aux slides Partie A de l'héritage. Il introduit la mécanique de base : créer une classe dérivée, appeler le constructeur parent, et ajouter des membres propres.
Pas de virtual ni override ici — c'est l'objet du codelab oo-04-inheritance (Partie B).
À la fin du codelab oo-03-encapsulation, la classe Snail est encapsulée :
class Snail
{
private int _energy;
public string Name { get; }
public ConsoleColor Color { get; }
public int X { get; private set; }
public int Y { get; private set; }
public int Energy
{
get { return _energy; }
private set { /* validation [10, 100] */ }
}
public Snail(string name, ConsoleColor color, int x, int y) { ... }
public void Move(int dx, int dy) { ... }
public void ReduceEnergy(int amount) { ... }
public void Draw() { ... }
public void Erase() { ... }
}
Tous les escargots se comportent de la même manière. On veut créer un type spécialisé sans copier-coller la classe.
À travers 4 étapes, vous apprendrez à :
: Snailbase(...)Créer GlitterSnail.cs avec la syntaxe : Snail et observer ce qui est hérité automatiquement.
Créez un nouveau fichier GlitterSnail.cs dans le même projet que Snail.cs :
class GlitterSnail : Snail
{
}
C'est intentionnellement minimal — on va voir ce que ça donne.
Compilez. Vous obtenez une erreur du type :
'GlitterSnail' does not contain a constructor that takes 0 arguments
ou
There is no argument given that corresponds to the required parameter 'name'
C# cherche un constructeur dans GlitterSnail, mais il n'y en a pas encore. La classe de base Snail exige name, color, x, y — il faut transmettre ces valeurs.
Même sans constructeur, lisez le code : GlitterSnail hérite automatiquement de Snail :
Name, Color, X, Y, EnergyMove(), ReduceEnergy(), Draw(), Erase()Dès qu'on aura un constructeur, un GlitterSnail pourra Draw(), Move(), etc. sans qu'on ait rien écrit.
Ajouter le constructeur de GlitterSnail en transmettant les paramètres à Snail via base(...).
Modifiez GlitterSnail.cs :
class GlitterSnail : Snail
{
public GlitterSnail(string name, ConsoleColor color, int x, int y)
: base(name, color, x, y)
{
// Le constructeur de Snail s'exécute d'abord (initialise Name, Color, X, Y, Energy)
// Le corps de GlitterSnail s'exécute ensuite (ici, rien de spécial pour l'instant)
}
}
: base(...)
| Reçoit les paramètres |
| Les transmet au constructeur de |
Corps | Code supplémentaire propre à |
new GlitterSnail("Stardust", ConsoleColor.Magenta, 0, 4)
→ 1. Snail(name, color, x, y) s'exécute : Name="Stardust", Energy=100, ...
→ 2. Corps de GlitterSnail() s'exécute : (rien pour l'instant)
Dans Program.cs, instanciez un GlitterSnail et appelez ses méthodes héritées :
GlitterSnail glitter = new GlitterSnail("Stardust", ConsoleColor.Magenta, 0, 4);
glitter.Draw(); // Hérité de Snail — fonctionne !
glitter.Move(2, 0); // Hérité de Snail — fonctionne !
Console.WriteLine(glitter.Name); // "Stardust"
Console.WriteLine(glitter.Energy); // 100
Compilez et exécutez. Tout fonctionne — sans avoir dupliqué une seule ligne de Snail.
GlitterSnail a quelque chose en plus : une intensité de scintillement et une méthode visuelle. Ces membres n'existent pas dans Snail.
Modifiez GlitterSnail.cs :
class GlitterSnail : Snail
{
public int GlitterIntensity { get; }
public GlitterSnail(string name, ConsoleColor color, int x, int y, int intensity)
: base(name, color, x, y)
{
GlitterIntensity = intensity;
}
public void Sparkle()
{
Console.ForegroundColor = Color;
for (int i = 0; i < GlitterIntensity; i++)
{
Console.Write("*");
}
Console.ResetColor();
}
}
|
| Non |
|
| Non |
|
| Oui |
GlitterSnail glitter = new GlitterSnail("Stardust", ConsoleColor.Magenta, 0, 4, 3);
glitter.Draw(); // Hérité de Snail
glitter.Sparkle(); // Propre à GlitterSnail → affiche "***"
glitter.Move(2, 0); // Hérité de Snail
Console.WriteLine(glitter.GlitterIntensity); // 3
// Un Snail ordinaire ne connaît pas Sparkle() :
Snail normal = new Snail("Bob", ConsoleColor.White, 0, 2);
// normal.Sparkle(); // ERREUR de compilation — Snail n'a pas Sparkle()
Compilez et vérifiez que Sparkle() produit des étoiles colorées dans la console.
Découvrir que GlitterSnail peut coexister avec Snail dans un tableau — sans encore utiliser override.
Snail[] snails = new Snail[]
{
new Snail("Bob", ConsoleColor.White, 0, 2),
new GlitterSnail("Stardust", ConsoleColor.Magenta, 0, 4, 3)
};
foreach (Snail snail in snails)
{
snail.Move(2, 0); // Les deux appellent Snail.Move() — identique pour l'instant
snail.Draw();
}
Compilez et exécutez. Les deux escargots se déplacent et s'affichent. La boucle traite un Snail et un GlitterSnail de la même manière.
GlitterSnailest unSnail (relation "is-a"). Partout où un Snail est attendu, un GlitterSnail peut être utilisé.
Les deux escargots appellent le même Move() — celui de Snail. Le GlitterSnail ne se déplace pas différemment. Pour changer ça, il faut virtual + override — c'est l'objet de la Partie B (oo-04-inheritance).
Classe dérivée |
| Hérite de tout sans duplication |
Constructeur parent |
| Initialise la partie |
Membre propre (propriété) |
| Propre à |
Membre propre (méthode) |
| Propre à |
Relation is-a |
|
|
Dans oo-04-inheritance, vous apprendrez à :
Move() comme virtual dans Snailoverride dans les classes dérivées